 
  

 






<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> 
<html>

<!-- Mirrored from www.javapractices.com/topic/TopicAction.do?Id=156 by HTTrack Website Copier/3.x [XR&CO'2010], Sun, 12 Jun 2011 17:28:07 GMT -->
<!-- Added by HTTrack --><meta http-equiv="content-type" content="text/html;charset=UTF-8"><!-- /Added by HTTrack -->
<head>
 <title>
  Java Practices -> Observers and listeners
 </title>
 <link rel="stylesheet" type="text/css" href="../stylesheet8.css" media="all">
 
 <link rel="shortcut icon" href='../images/favicon.ico' type="image/vnd.microsoft.icon">
 <meta name="description" content="Concise presentations of java programming practices, tasks, and conventions, amply illustrated with syntax highlighted code examples.">
 
 <meta name='keywords' content='CurrentPortfolio,FileSaveAction,publish,subscribe,SummaryView,listener,observer,swing,java,java programming,java practices,java idiom,java style,java design patterns,java coding conventions,'>
 
 
</head>
 
<body>


<div class='menu-bar'>
 
  <a href='../home/HomeAction.html' title='Table of Contents'>Home</a> |
  <a href='../vote/VoteSummaryAction-2.html' title='View Poll Results'>Poll</a> |
   
  <A href='../feedback/FeedbackAction451f-2.html?Operation=Show' title='Send Your Feedback'>Wiki</a> |
  <b><a href='../source/SourceAction-2.html' title='Grab Source Code'>Source Code</a></b><IMG class='no-margin' SRC="../images/goldstar.gif" ALT=""> |

  <a href='http://www.web4j.com/Java_Web_Application_Framework_Overview.jsp?From=1' title='Free Download - Java Web Application Framework'><b>WEB4J</b></a> |
  
  <a href='http://www.date4j.net/' title='Replacement for java.util.Date'><b>DATE4J</b></a> |

   <a href='../references/ReferencesAction-2.html' title='References'>Links</a>
   
  <form action='http://www.javapractices.com/search/SearchAction.do' method='get' class='search-form'>
   <input type='text' name='SearchTerms' value="" size=12 maxlength=50 class='search'>
   <input type='submit' value="Search">
  </form>
 
</div>

<P>



  

 






<p class="display-messages">

 

 

</p>


<div class="main-layout">
 
   

 




<div class='page-title'>Observers and listeners</div>

<div class='main-body'>
 
<br>The Observer pattern (also known as Listener, or Publish-Subscribe)
is particularly useful for graphical applications.
<p>The general idea is that one or more objects (the subscribers) register
their interest in being notified of changes to another object (the publisher).
The subscribers can also change the state of the publisher, although this
is not obligatory (one might call these "active" observers, as opposed
to "passive" ones, which do not change the state of the publisher). Interfaces
are used to ensure that publishers and subscribers have only minimal knowledge
of each other.
<p>When using Swing, there is a choice among using <tt><a href="http://java.sun.com/javase/6/docs/api/java/util/Observable.html">Observable</a></tt>,
<tt><a href="http://java.sun.com/javase/6/docs/api/java/util/Observer.html">Observer</a></tt>
, or the many <tt>XXXListener</tt> interfaces which apply to GUI components.
<p>Although <tt>Observer</tt> is indeed an interface, <tt>Observable</tt>
is neither an interface nor an abstract base class : <i>it is a concrete
class</i>. This is very unusual. Almost all implementations of Design Patterns
define the important items as either interfaces or abstract base classes,
not as concrete classes.
<p><b>Extended Example</b>
<p><tt>CurrentPortfolio</tt> is a non-graphical class which encapsulates
data regarding a set of stocks - a stock portfolio. It is the central abstraction
of the user interface, and a number of other classes need to interact with
it, both as active and passive listeners. It extends <tt><a href="http://java.sun.com/javase/6/docs/api/java/util/Observable.html">Observable</a></tt>
since it is a non-graphical class.
<br>
<PRE>

<span class='keyword'>package</span> hirondelle.stocks.portfolio;

<span class='keyword'>import</span> java.util.Observable;
<span class='keyword'>import</span> java.util.*;
<span class='keyword'>import</span> hirondelle.stocks.util.Args;
<span class='keyword'>import</span> hirondelle.stocks.quotes.Stock;

<span class='comment'>/**
 * The central abstraction of this package, representing the current selection of 
 * stocks of interest to the end user 
 * (a {@link hirondelle.stocks.portfolio.Portfolio}).
 * 
 * &lt;P&gt;&lt;tt&gt;CurrentPortfolio&lt;/tt&gt; may be used as an example implementation for any
 * application which edits items one at a time.
 * 
 * &lt;p&gt;The {@link #isUntitled} and {@link #getNeedsSave} properties are particularly
 * significant. They influence the file menu actions. For example, a
 * &lt;tt&gt;CurrentPortfolio&lt;/tt&gt; for which {@link #isUntitled} is true cannot be deleted.
 * 
 * &lt;p&gt;&lt;tt&gt;CurrentPortfolio&lt;/tt&gt; is an {@link java.util.Observable}. To minimize spurious
 * updates, related {@link java.util.Observer} objects need to call
 * {@link java.util.Observable#notifyObservers()} explicitly. This is important in this
 * application, since quotes are fetched from the web each time the current portfolio is
 * updated, and this is a relatively expensive operation.
 */</span>
<span class='keyword'>public</span> <span class='keyword'>final</span> <span class='keyword'>class</span> CurrentPortfolio <span class='keyword'>extends</span> Observable {

  <span class='comment'>/**
   * Constructor.
   *  
   * @param aPortfolio is the set of stocks of current interest to the user; no 
   * defensive copy is made of &lt;tt&gt;aPortfolio&lt;/tt&gt;.
   * @param aNeedsSave is true only if this &lt;tt&gt;CurrentPortfolio&lt;/tt&gt; 
   * has been edited by the end user, and these edits have not yet been saved.
   */</span>
  <span class='keyword'>public</span> CurrentPortfolio(Portfolio aPortfolio, NeedsSave aNeedsSave) {
    Args.checkForNull(aPortfolio);
    fPortfolio = aPortfolio;
    fNeedsSave = aNeedsSave.getValue();
    <span class='comment'>// upon construction of the main window, an update is desired in order to
</span>    <span class='comment'>// synch the gui with the current portfolio. This update is called explicitly.
</span>    <span class='comment'>// Thus, setChanged needs to be set here, since it's default value is false.
</span>    setChanged();
  }

  <span class='comment'>/**
  * Enumeration for the two states of &lt;tt&gt;aNeedsSave&lt;/tt&gt; passed to the constructor.
  * Use of an enumeration forces the caller to create a constructor call which has
  * high clarity.
  */</span>
  <span class='keyword'>public</span> <span class='keyword'>enum</span> NeedsSave {
    TRUE(<span class='keyword'>true</span>),
    FALSE(<span class='keyword'>false</span>);
    <span class='keyword'>boolean</span> getValue() {
      <span class='keyword'>return</span> fToggle;
    }
    <span class='keyword'>private</span> <span class='keyword'>final</span> <span class='keyword'>boolean</span> fToggle;
    <span class='keyword'>private</span> NeedsSave(<span class='keyword'>boolean</span> aToggle) {
      fToggle = aToggle;
    }
  }
  

  <span class='comment'>/**
   * Revert to an untitled &lt;tt&gt;Portfolio&lt;/tt&gt; which does not need a save.
   */</span>
  <span class='keyword'>public</span> <span class='keyword'>void</span> clear() {
    setPortfolio(Portfolio.getUntitledPortfolio());
    setNeedsSave(<span class='keyword'>false</span>);
  }

  <span class='comment'>/**
   * Return &lt;tt&gt;true&lt;/tt&gt; only if the current &lt;tt&gt;Portfolio&lt;/tt&gt; has never been
   * saved under a user-specified name, neither in this session, nor in any other. Such a
   * &lt;tt&gt;Portfolio&lt;/tt&gt; appears as untitled in the display.
   */</span>
  <span class='keyword'>public</span> <span class='keyword'>boolean</span> isUntitled() {
    <span class='keyword'>return</span> fPortfolio.isUntitled();
  }

  <span class='comment'>/**
   * Return the {@link Portfolio} of current interest to the user.
   */</span>
  <span class='keyword'>public</span> Portfolio getPortfolio() {
    <span class='keyword'>return</span> fPortfolio;
  }

  <span class='comment'>/**
   * Change the {@link Portfolio} of current interest to the user.
   */</span>
  <span class='keyword'>public</span> <span class='keyword'>void</span> setPortfolio(Portfolio aPortfolio) {
    Args.checkForNull(aPortfolio);
    fPortfolio = aPortfolio;
    setChanged();
  }

  <span class='comment'>/**
   * Return the name of this &lt;tt&gt;CurrentPortfolio&lt;/tt&gt;.
   */</span>
  <span class='keyword'>public</span> String getName() {
    <span class='keyword'>return</span> fPortfolio.getName();
  }

  <span class='comment'>/**
   * Change the name of this &lt;tt&gt;CurrentPortfolio&lt;/tt&gt;.
   * @param aName has the same conditions as 
   * {@link hirondelle.stocks.portfolio.Portfolio#setName(String)}.
   */</span>
  <span class='keyword'>public</span> <span class='keyword'>void</span> setName(String aName) {
    fPortfolio.setName(aName);
    setChanged();
  }

  <span class='comment'>/**
   * Return the {@link hirondelle.stocks.quotes.Stock} objects in this
   * &lt;tt&gt;CurrentPortfolio&lt;/tt&gt;.
   */</span>
  <span class='keyword'>public</span> Set&lt;Stock&gt; getStocks() {
    <span class='keyword'>return</span> fPortfolio.getStocks();
  }

  <span class='comment'>/**
   * Change the stocks in this &lt;tt&gt;CurrentPortfolio&lt;/tt&gt;.
   * @param aStocks has the same conditions as
   * {@link hirondelle.stocks.portfolio.Portfolio#setStocks(Set)}
   */</span>
  <span class='keyword'>public</span> <span class='keyword'>void</span> setStocks(Set&lt;Stock&gt; aStocks) {
    fPortfolio.setStocks(aStocks);
    setChanged();
  }

  <span class='comment'>/**
   * Return &lt;tt&gt;true&lt;/tt&gt; only if this &lt;tt&gt;CurrentPortfolio&lt;/tt&gt; has unsaved
   * edits.
   */</span>
  <span class='keyword'>public</span> <span class='keyword'>boolean</span> getNeedsSave() {
    <span class='keyword'>return</span> fNeedsSave;
  }

  <span class='comment'>/**
   * Indicate that this &lt;tt&gt;CurrentPortfolio&lt;/tt&gt; either does or does not have any
   * unsaved edits.
   */</span>
  <span class='keyword'>public</span> <span class='keyword'>void</span> setNeedsSave(<span class='keyword'>boolean</span> aNeedsSave) {
    fNeedsSave = aNeedsSave;
    setChanged();
  }

  <span class='comment'>// PRIVATE //
</span>  <span class='keyword'>private</span> Portfolio fPortfolio;
  <span class='keyword'>private</span> <span class='keyword'>boolean</span> fNeedsSave;
}
 
</PRE>
<br>
<br><tt>FileSaveAction</tt> is an "active" <tt>Observer</tt> : it both
reacts to the <tt>CurrentPortfolio</tt> and acts upon it. It reacts to
<tt>CurrentPortfolio</tt>
since it is enabled only when the <tt>CurrentPortfolio</tt> has unsaved
edits. When <tt>FileSaveAction</tt> is executed, on the other hand, it
acts upon <tt>CurrentPortfolio</tt> by changing its state to "no unsaved
edits".
<p>(Note that <tt>FileSaveAction.actionPerformed</tt> can simply ignore
its <tt>ActionEvent</tt> argument, since it already has a reference to
the <tt>CurrentPortfolio</tt>.)
<br>
<PRE>

<span class='keyword'>package</span> hirondelle.stocks.file;

<span class='keyword'>import</span> java.awt.event.*;
<span class='keyword'>import</span> javax.swing.*;
<span class='keyword'>import</span> java.util.*;
<span class='keyword'>import</span> hirondelle.stocks.portfolio.PortfolioDAO;
<span class='keyword'>import</span> hirondelle.stocks.portfolio.CurrentPortfolio;
<span class='keyword'>import</span> hirondelle.stocks.util.ui.UiUtil;
<span class='keyword'>import</span> java.util.logging.Logger;
<span class='keyword'>import</span> hirondelle.stocks.util.Util;

<span class='comment'>/**
* Save the edits performed on the {@link CurrentPortfolio}, and update the display 
* to show that the &lt;tt&gt;CurrentPortfolio&lt;/tt&gt; no longer needs a save.
*/</span>
<span class='keyword'>public</span> <span class='keyword'>final</span> <span class='keyword'>class</span> FileSaveAction <span class='keyword'>extends</span> AbstractAction <span class='keyword'>implements</span> Observer {

  <span class='comment'>/**
  * Constructor.
  *  
  * @param aCurrentPortfolio is to be saved by this action.
  */</span>
  <span class='keyword'>public</span> FileSaveAction(CurrentPortfolio aCurrentPortfolio) {
    <span class='keyword'>super</span>(<span class='literal'>"Save"</span>, UiUtil.getImageIcon(<span class='literal'>"/toolbarButtonGraphics/general/Save"</span>)); 
    fCurrentPortfolio = aCurrentPortfolio;
    fCurrentPortfolio.addObserver( <span class='keyword'>this</span> );
    putValue(SHORT_DESCRIPTION, <span class='literal'>"Save edits to the current portfolio"</span>);
    putValue(
      ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_S, ActionEvent.CTRL_MASK)
    );
    putValue(LONG_DESCRIPTION, <span class='literal'>"Save edits to the current portfolio"</span>);
    putValue(MNEMONIC_KEY, <span class='keyword'>new</span> Integer(KeyEvent.VK_S) );    
  }

  <span class='keyword'>public</span> <span class='keyword'>void</span> actionPerformed(ActionEvent e) {
    fLogger.info(<span class='literal'>"Saving edits to the current portfolio."</span>);
    PortfolioDAO portfolioDAO = <span class='keyword'>new</span> PortfolioDAO();
    portfolioDAO.save( fCurrentPortfolio.getPortfolio() );
    fCurrentPortfolio.setNeedsSave(<span class='keyword'>false</span>);
    fCurrentPortfolio.notifyObservers();
  }  
  
  <span class='comment'>/**
  * Synchronize the state of this object with the state of the 
  * &lt;tt&gt;CurrentPortfolio&lt;/tt&gt; passed to the constructor.
  *
  * This action is enabled only when the &lt;tt&gt;CurrentPortfolio&lt;/tt&gt; is titled and 
  * needs a save.
  */</span>
  <span class='keyword'>public</span> <span class='keyword'>void</span> update(Observable aPublisher, Object aData) {
    setEnabled( fCurrentPortfolio.getNeedsSave() &amp;&amp; !fCurrentPortfolio.isUntitled() );
  } 
  
  <span class='comment'>// PRIVATE //
</span>  <span class='keyword'>private</span> CurrentPortfolio fCurrentPortfolio;
  <span class='keyword'>private</span> <span class='keyword'>static</span> <span class='keyword'>final</span> Logger fLogger = Util.getLogger(FileSaveAction.<span class='keyword'>class</span>);
}
 
</PRE>
<br>
<br><tt>SummaryView</tt> is graphical component, which is a passive listener
of another graphical component called <tt>QuoteFilterFactory</tt> (see
<a href="TopicAction167e-2.html">Filter
table rows</a> for more information). The role of the <tt>QuoteFilterFactory</tt>
is to return an object which allows its listeners - such as <tt>SummaryView</tt>
- to limit calculations to only those stocks which satisfy some particular
criterion. When the user selects a GUI element in <tt>QuoteFilterFactory</tt>,
then a <tt>PropertyChangeEvent</tt> is broadcast to its listeners.
<br>
<PRE>

<span class='keyword'>package</span> hirondelle.stocks.quotes;

<span class='keyword'>import</span> java.util.*;
<span class='keyword'>import</span> java.util.logging.*;
<span class='keyword'>import</span> javax.swing.*;
<span class='keyword'>import</span> java.awt.*;
<span class='keyword'>import</span> java.beans.*;
<span class='keyword'>import</span> java.math.BigDecimal;

<span class='keyword'>import</span> hirondelle.stocks.table.QuoteFilter;
<span class='keyword'>import</span> hirondelle.stocks.util.Args;
<span class='keyword'>import</span> hirondelle.stocks.util.ui.UiConsts;
<span class='keyword'>import</span> hirondelle.stocks.util.ui.UiUtil;
<span class='keyword'>import</span> hirondelle.stocks.table.QuoteFilterFactory;
<span class='keyword'>import</span> hirondelle.stocks.portfolio.CurrentPortfolio;
<span class='keyword'>import</span> hirondelle.stocks.util.Util;

<span class='comment'>/**
 * Component placed on the main screen to present summary information
 * regarding the {@link CurrentPortfolio} to the user.
 * 
 * &lt;P&gt; Monetary values are presented with zero decimal places, and percentages 
 * are presented with 2 decimal places.
 */</span>
<span class='keyword'>public</span> <span class='keyword'>final</span> <span class='keyword'>class</span> SummaryView <span class='keyword'>extends</span> JPanel <span class='keyword'>implements</span> PropertyChangeListener {

  <span class='comment'>/**
   * Constructor. 
   * 
   * @param aCurrentPortfolio summarized by this class
   * @param aQuoteFilterFactory source of a {@link QuoteFilter} used to
   * limit this summary to only certain items.
   */</span>
  <span class='keyword'>public</span> SummaryView(
    CurrentPortfolio aCurrentPortfolio, QuoteFilterFactory aQuoteFilterFactory
  ) {
    Args.checkForNull(aCurrentPortfolio);
    fCurrentPortfolio = aCurrentPortfolio;
    fQuoteFilterFactory = aQuoteFilterFactory;
    fQuoteFilterFactory.addPropertyChangeListener(<span class='keyword'>this</span>);
    LayoutManager layout = <span class='keyword'>new</span> BoxLayout(<span class='keyword'>this</span>, BoxLayout.Y_AXIS);
    setLayout(layout);
    add(getSummaryFields());
    add(Box.createVerticalStrut(UiConsts.ONE_SPACE));
    add(getTimeLastUpdateField());
    add(Box.createVerticalGlue());
    add(getStatusField());
  }

  <span class='comment'>/**
   * Update this &lt;tt&gt;SummaryView&lt;/tt&gt; in response to selection by user of a new
   * criterion for filtering items.
   * 
   * &lt;P&gt; Listens to the {@link QuoteFilterFactory} passed to the constructor.
   * @param event processed only if its &lt;tt&gt;getPropertyName&lt;/tt&gt; is equal to
   * &lt;tt&gt;QuoteFilterFactory.SELECTED_FILTER&lt;/tt&gt;.
   */</span>
  <span class='keyword'>public</span> <span class='keyword'>void</span> propertyChange(PropertyChangeEvent event) {
    <span class='keyword'>boolean</span> isUndesiredEvent = !event.getPropertyName().equals(
      QuoteFilterFactory.SELECTED_FILTER
    );
    <span class='keyword'>if</span> (isUndesiredEvent) {
      fLogger.finer(<span class='literal'>"SummaryView DISCARDING event..."</span>);
    }
    <span class='keyword'>else</span> {
      fLogger.finer(<span class='literal'>"SummaryView processing event..."</span>);
      updateView();
    }
  }

  <span class='comment'>/**
   * Display summary information for the {@link CurrentPortfolio}, adding any filtering
   * according to the {@link QuoteFilterFactory} passed to the constructor.
   * 
   * &lt;P&gt;Use a {@link ColorTip} to draw the user's attention to the fresh 
   * quote information, by highlighting the time of last update for a few seconds.
   * @param aQuotes contains a {@link Quote} for every
   * {@link Stock} in the {@link CurrentPortfolio}.
   */</span>
  <span class='keyword'>void</span> setQuotes(Collection&lt;Quote&gt; aQuotes) {
    fQuotes = aQuotes;
    ColorTip colorTip = <span class='keyword'>new</span> ColorTip(<span class='literal'>0</span>, <span class='literal'>2</span>, fTimeLastUpdate, Color.yellow);
    colorTip.start();
    updateView();
  }

  <span class='comment'>/**
   * Present short text to the user indicating success or failure of the most recent
   * {@link FetchQuotesAction}.
   * 
   * &lt;P&gt;In the case of failure, &lt;tt&gt;aMessage&lt;/tt&gt; should indicate remedial measures.
   * @param aMessage has visible content
   */</span>
  <span class='keyword'>void</span> showStatusMessage(String aMessage) {
    Args.checkForContent(aMessage);
    fStatusMessage.setText(aMessage);
  }

  <span class='comment'>// PRIVATE //
</span>  <span class='keyword'>private</span> CurrentPortfolio fCurrentPortfolio;
  <span class='keyword'>private</span> QuoteFilterFactory fQuoteFilterFactory;
  <span class='keyword'>private</span> Collection&lt;Quote&gt; fQuotes;

  <span class='keyword'>private</span> JLabel fBookValue;
  <span class='keyword'>private</span> JLabel fCurrentValue;
  <span class='keyword'>private</span> JLabel fProfit;
  <span class='keyword'>private</span> JLabel fPercentageProfit;
  <span class='keyword'>private</span> JLabel fTimeLastUpdate;
  <span class='keyword'>private</span> JLabel fStatusMessage;

  <span class='keyword'>private</span> <span class='keyword'>static</span> <span class='keyword'>final</span> Logger fLogger = Util.getLogger(SummaryView.<span class='keyword'>class</span>);

  <span class='keyword'>private</span> JComponent getSummaryFields() {
    JPanel content = <span class='keyword'>new</span> JPanel();
    LayoutManager layout = <span class='keyword'>new</span> BoxLayout(content, BoxLayout.X_AXIS);
    content.setLayout(layout);
    content.add(getValueFields());
    content.add(Box.createHorizontalGlue());
    content.add(getProfitFields());
    <span class='keyword'>return</span> content;
  }

  <span class='keyword'>private</span> JComponent getValueFields() {
    JPanel content = <span class='keyword'>new</span> JPanel();
    content.setLayout(<span class='keyword'>new</span> GridBagLayout());
    fBookValue = UiUtil.addSimpleDisplayField(
      content, <span class='literal'>"Book Value"</span>, <span class='keyword'>null</span>, UiUtil.getConstraints(<span class='literal'>0</span>,<span class='literal'>0</span>), <span class='keyword'>false</span>
    );
    fBookValue.setToolTipText(<span class='literal'>"Acquisition cost of the portfolio"</span>);
    fCurrentValue = UiUtil.addSimpleDisplayField(
      content, <span class='literal'>"Current Value"</span>, <span class='keyword'>null</span>, UiUtil.getConstraints(<span class='literal'>1</span>, <span class='literal'>0</span>), <span class='keyword'>false</span>
    );
    fCurrentValue.setToolTipText(<span class='literal'>"Current value of the portfolio"</span>);
    <span class='keyword'>return</span> content;
  }

  <span class='keyword'>private</span> JComponent getProfitFields() {
    JPanel content = <span class='keyword'>new</span> JPanel();
    content.setLayout(<span class='keyword'>new</span> GridBagLayout());
    fProfit = UiUtil.addSimpleDisplayField(
      content, <span class='literal'>"Profit"</span>, <span class='keyword'>null</span>, UiUtil.getConstraints(<span class='literal'>0</span>, <span class='literal'>0</span>), <span class='keyword'>false</span>
    );
    fProfit.setToolTipText(<span class='literal'>"Current value minus book value"</span>);
    fPercentageProfit = UiUtil.addSimpleDisplayField(
      content, <span class='literal'>"% Profit"</span>, <span class='keyword'>null</span>, UiUtil.getConstraints(<span class='literal'>1</span>, <span class='literal'>0</span>), <span class='keyword'>false</span>
    );
    fPercentageProfit.setToolTipText(<span class='literal'>"Profit divided by book value, as percent"</span>);
    <span class='keyword'>return</span> content;
  }

  <span class='keyword'>private</span> JComponent getTimeLastUpdateField() {
    JPanel content = <span class='keyword'>new</span> JPanel();
    content.setLayout(<span class='keyword'>new</span> GridBagLayout());
    fTimeLastUpdate = UiUtil.addSimpleDisplayField(
      content, <span class='literal'>"Last Update"</span>, <span class='keyword'>null</span>, UiUtil.getConstraints(<span class='literal'>0</span>, <span class='literal'>0</span>), <span class='keyword'>false</span>
    );
    <span class='keyword'>return</span> content;
  }

  <span class='keyword'>private</span> JComponent getStatusField() {
    JPanel content = <span class='keyword'>new</span> JPanel();
    content.setLayout(<span class='keyword'>new</span> BoxLayout(content, BoxLayout.X_AXIS));
    fStatusMessage = UiUtil.addSimpleDisplayField(
      content, <span class='literal'>"Status"</span>, <span class='keyword'>null</span>, UiUtil.getConstraints(<span class='literal'>0</span>,<span class='literal'>0</span>), <span class='keyword'>false</span>
    );
    content.add(Box.createHorizontalGlue());
    <span class='keyword'>return</span> content;
  }

  <span class='keyword'>private</span> <span class='keyword'>void</span> updateView() {
    QuoteFilter filter = fQuoteFilterFactory.getSelectedFilter();
    Collection&lt;Quote&gt; filteredQuotes = filter.sift(fQuotes);

    fBookValue.setText(getBookValue(filteredQuotes));
    fCurrentValue.setText(getCurrentValue(filteredQuotes));
    fProfit.setText(getProfit(filteredQuotes));
    fPercentageProfit.setText(getPercentageProfit(filteredQuotes));
    fTimeLastUpdate.setText(UiUtil.getLocalizedTime(<span class='keyword'>new</span> Date()));
  }

  <span class='keyword'>private</span> String getBookValue(Collection&lt;Quote&gt; aQuotes) {
    Number value = fCurrentPortfolio.getPortfolio().getBookValue(aQuotes);
    <span class='keyword'>return</span> UiUtil.getLocalizedInteger(value);
  }

  <span class='keyword'>private</span> String getCurrentValue(Collection&lt;Quote&gt; aQuotes) {
    Number value = fCurrentPortfolio.getPortfolio().getCurrentValue(aQuotes);
    <span class='keyword'>return</span> UiUtil.getLocalizedInteger(value);
  }

  <span class='keyword'>private</span> String getProfit(Collection&lt;Quote&gt; aQuotes) {
    Number value = fCurrentPortfolio.getPortfolio().getProfit(aQuotes);
    <span class='keyword'>return</span> UiUtil.getLocalizedInteger(value);
  }

  <span class='keyword'>private</span> String getPercentageProfit(Collection&lt;Quote&gt; aQuotes) {
    BigDecimal value = fCurrentPortfolio.getPortfolio().getPercentageProfit(aQuotes);
    <span class='keyword'>return</span> UiUtil.getLocalizedPercent(value);
  }
}
 
</PRE>
<br>
<br>
<br>

</div>




<div class='topic-section'>See Also :</div>
<div class='main-body'>
 
  
  <a href='TopicAction167e-2.html?Id=163'>Filter table rows</a> <br>
 
</div>


<div class='topic-section'>Would you use this technique?</div>
<div class='main-body'>
  
  <form action="http://www.javapractices.com/vote/AddVoteAction.do" method='post'>
    Yes<input type='radio' name='Choice' value='Y' >
    &nbsp;&nbsp;No<input type='radio' name='Choice' value='N'>
    &nbsp;&nbsp;Undecided<input type='radio' name='Choice' value="?" >
    &nbsp;&nbsp;<input type=submit value="Vote" >
    <input type='hidden' name='Operation' value='Apply'>
    <input type='hidden' name='TopicId' value='156'>
  </form>
</div>

<div style='height:10.0em;'></div>

 
 
</div>

  

 





<div align='center' class='legalese'>  
&copy; 2011 Hirondelle Systems |
<a href='../source/SourceAction-2.html'><b>Source Code</b></a><IMG class='no-margin' SRC="../images/goldstar.gif" ALT=""> |
<a href="mailto:webmaster@javapractices.com">Contact</a> |
<a href="http://creativecommons.org/licenses/by-nc-sa/1.0/">License</a> |
<a href='../apps/cjp.rss'>RSS</a>
<!-- ukey="2AC36CD2" -->
<!-- ckey="16DF3D87" -->
<br>

 Individual code snippets can be used under this <a href='../LICENSE.txt'>BSD license</a> - Last updated on June 6, 2010.<br>
 Over 150,000 unique IPs last month - <span title='Java Practices 2.6.5, Mon May 16 00:00:00 EDT 2011'>Built with</span> <a href='http://www.web4j.com/'>WEB4J</a>.<br>
 - In Memoriam : Bill Dirani -
</div>

<script src="../../www.google-analytics.com/urchin.js" type="text/javascript">
</script>
<script type="text/javascript">
_uacct = "UA-2633428-1";
urchinTracker();
</script>



</body>

<!-- Mirrored from www.javapractices.com/topic/TopicAction.do?Id=156 by HTTrack Website Copier/3.x [XR&CO'2010], Sun, 12 Jun 2011 17:28:07 GMT -->
<!-- Added by HTTrack --><meta http-equiv="content-type" content="text/html;charset=UTF-8"><!-- /Added by HTTrack -->
</html>
